<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /*
        1.声明的方法:在函数名称前面加一个星号(*)
            注意:箭头函数不能用来定义生成器函数
     */

    // 生成器函数声明
    function* f1() {
    }

    // 生成器函数表达式
    let f2 = function* () {

    }

    // 作为对象字面量方法的生成器函数
    let foo = {
        * f3() {
        }
    }

    // 作为类实例方法的生成器函数
    class F4 {
        * f5() {
        }
    }

    // 作为类静态方法的生成器函数
    class Bar {
        static* generatorFn() {
        }
    }

    /*
        2.生成器对象也实现了Iterator接口,也具有next()方法
     */

    // 2.1.函数体为空的: 生成器中间不会停留,调用一次next()就会达到done:true的状态
    function* generatorFn2() {
    }

    let generatorObject = generatorFn2();
    console.log(generatorObject.next());// {value:undefined,done:true}

    // 2.2 value属性是生成器的返回值,默认为undefined,可以通过生成器的返回值指定
    function* generatorFn3() {
        return 'foo'
    }

    let g3 = generatorFn3();
    console.log(g3) // generatorFn3{<suspended>}
    // fixme:注意这里和前面的迭代器对象返回的不同,之前done为true的时候,value必定为undefined
    console.log(g3.next()) // {value:'foo',done:true}

    // 2.3 生成器函数只会在初次调用next()方法后开始执行
    function* generatorFn4() {
        console.log('foo')
    }

    //  初次调用生成器函数并不会打印日志
    let g4 = generatorFn4();
    console.log(g4.next())// foo {value:undefined,done:true}

    // 2.4. 生成器对象实现了Iterable接口,默认的迭代器是自引用的
    function* generatorFn5() {
        return 'ojjk'
    }

    console.log(generatorFn5) // ƒ* generatorFn5() {}
    let result = generatorFn5()[Symbol.iterator]()
    let result2 = generatorFn5();
    console.log(result.next())  // {value:'ojjk',done:true}
    console.log(result2.next())  // {value:'ojjk',done:true}
    
</script>
</body>
</html>